home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.5)
-
- from __future__ import with_statement
- import sys
- import logging
- import struct
- import socket
- import collections
- import time
- from threading import RLock
- from traceback import print_exc
- import hub
- import common
- import oscar
- from oscar.Snactivator import Snactivator
- from util import lock, unpack_named, Storage, to_hex, try_this, callsback, isgeneratormethod
- log = logging.getLogger('oscar.sock')
- from struct import pack, unpack
- from common import netcall
-
- def flap_sequence_number():
- i = 1
- while None:
- yield i
- i += 1
- if i >= 32768:
- i = 1
- continue
- continue
- return None
-
-
- class OscarSocket(common.socket):
- flap_hdr_size = 6
- snac_hdr_size = 10
- id = 42
- func_templ = '\n def %(name)s (self):\n print "%(name)s is not implemented!"\n print self.hdr\n print self.data\n '
-
- def default_cb(self, *a, **kw):
- log.debug_s('Socket ignoring (%s, %s)', a, kw)
-
-
- def __repr__(self):
-
- try:
- return '<OscarSocket %r>' % (self._OscarSocket__oserver,)
- except Exception:
- return '<OscarSocket ??>'
-
-
-
- def __init__(self, server, cookie = None, incoming = None, close = None, callback = None, bos = False):
- common.socket.__init__(self)
- if not callback:
- pass
- self.on_connect = self.default_cb
- if not incoming:
- pass
- self.on_incoming = self.default_cb
- if not close:
- pass
- self.on_close = self.default_cb
- self.callbacks = collections.defaultdict(list)
- self.cookie = cookie
- self.rate_lock = RLock()
- self.hdr = None
- self.buf = ''
- self.data = ''
- self.seq = flap_sequence_number()
- self.req = flap_sequence_number()
- self.rate_classes = []
- self.rates = { }
- self.rate_lvl_incr = False
- self.snactivate = self._send_snac
- self.snactivator = None
- self.bos = bos
- self.set_terminator(self.flap_hdr_size)
- log.info('oscar socket created, connecting to %s', server)
- self._OscarSocket__oserver = server
- self.connect(server, error = callback.error)
-
- __init__ = callsback(__init__)
-
- def handle_error(self, e = None):
- if isinstance(e, socket.error):
- if self.on_close is not None:
- log.error('Socket error for %r, calling on_close (= %r): %r', self, self.on_close, e)
- self.on_close(self)
- else:
- log.info('handle_error in %r but on_close is None' % self)
-
- common.socket.handle_error(self, e)
-
-
- def test_connection(self):
-
- try:
- self.send_flap(5)
- except Exception:
- e = None
- print_exc()
- if not self.on_close:
- pass
- self.default_cb(self)
-
-
-
- def apply_rates(self, rate_classes, rate_groups):
- if not self.rate_classes:
- self.rate_classes = rate_classes
- else:
- for rates in rate_classes:
- id = rates[0]
- self.rate_classes[id - 1] = rates
-
- self.rates.update(rate_groups)
- if self.snactivator is None:
- self.snactivator = Snactivator(self)
- self.snactivator.start()
-
- self.snactivate = self.snactivator.send_snac
-
- apply_rates = lock(apply_rates)
-
- def calc_rate_level(self, rate_class):
- old_level = rate_class.current_level
- window = rate_class.window
- now = int(time.time())
- time_diff = (now - rate_class.last_time) * 1000
- new_level = min(int(((window - 1) * old_level + time_diff) / window), rate_class.max_level)
- return (new_level, now)
-
-
- def snac_rate_class(self, fam, sub, *a):
-
- try:
- return self.rate_classes[self.rates[(fam, sub)] - 1]
- except KeyError:
- return None
-
-
-
- def _get_rate_lvls(self, rclass):
- return (rclass.max_level, rclass.current_level, rclass.alert_level, rclass.clear_level, rclass.window)
-
-
- def time_to_send(self, s):
- fam = s[0]
- sub = s[1]
- rclass = self.snac_rate_class(fam, sub)
- (ml, curl, al, clrl, w) = self._get_rate_lvls(rclass)
- threshold = min(ml, al + (clrl - al) * 2)
- self.rate_lock.__enter__()
-
- try:
- if (curl < al or self.rate_lvl_incr) and curl < threshold:
- self.rate_lvl_incr = True
- else:
- self.rate_lvl_incr = False
- return 0
- finally:
- pass
-
- k = 500
- step = ml / k
- wait = w * step + curl
- delta = rclass.last_time - int(time.time())
- to_send = delta + wait / 1000
- return max(0, to_send)
-
-
- def handle_connect(self):
- log.debug('connected')
-
-
- def handle_close(self):
- log.info('closed. calling on_close=%r', self.on_close)
- if not self.on_close:
- pass
- self.default_cb(self)
- self.close()
-
-
- def handle_expt(self):
- log.warning('oob data')
- self.handle_close()
-
-
- def collect_incoming_data(self, data):
- pass
-
-
- def set_terminator(self, term):
- common.socket.set_terminator(self, term)
-
-
- def found_terminator(self):
-
- try:
- if self.hdr is None:
- self._lock.__enter__()
-
- try:
- self.hdr = unpack_named('!BBHH', 'id', 'chan', 'seq', 'size', self.buf)
- self.buf = ''
- if self.hdr.size == 0:
- self.found_terminator()
- else:
- self.set_terminator(self.hdr.size)
- finally:
- pass
-
- else:
-
- try:
- getattr(self, 'channel_%d' % self.hdr.chan, self.unknown_channel)()
- except oscar.errors:
- e = None
- hub.get_instance().on_error(e)
- except Exception:
- log.critical('Error handling FLAP 0x%x (DATA: %s) ' % (self.hdr.seq, repr(self.data)))
- raise
- finally:
- self._lock.__enter__()
-
- try:
- (self.hdr, self.data) = (None, '')
- self.set_terminator(self.flap_hdr_size)
- finally:
- pass
-
-
- except socket.error:
- raise
- except Exception:
- e = None
- log.critical('%r had a non-socket error', self)
- print_exc()
- finally:
- if self.terminator == 0:
- log.critical('terminator was 0, closing socket!')
- self.handle_close()
-
-
-
-
- def close(self):
- del self.on_incoming
- self.on_incoming = None
- common.socket.close(self)
-
-
- def close_when_done(self):
- self.on_close = None
- if self.snactivator:
- self.snactivator.stop()
- del self.snactivator
- self.snactivator = None
-
-
- try:
- self.send_flap(4)
- except socket.error:
- (errno, desc) = None
- if errno not in (9, 10054, 10057):
- raise
-
- except:
- errno not in (9, 10054, 10057)
-
- common.socket.close_when_done(self)
-
-
- def send_flap(self, chan, data = ''):
- log.debug_s('Sending FLAP on channel %d, data is < %r >', chan, data)
- (None, None, netcall)((lambda : common.socket.push(self, pack('!BBHH', self.id, chan, self.seq.next(), len(data)) + data)))
-
-
- def send_snac(self, fam, sub, data = '', priority = 5, req = False, cb = None, *args, **kwargs):
- req_id = self.req.next()
- if req:
- for k, v in list(self.callbacks.iteritems()):
- if not v:
- self.callbacks.pop(k)
- continue
-
- self.callbacks[req_id].append((cb, args, kwargs))
-
- self.snactivate((fam, sub, req_id, data), priority)
-
-
- def _send_snac(self, .1, priority = None):
- (fam, sub, req_id, data) = .1
- server_version = getattr(self, 'server_snac_versions', { }).get(fam, None)
- if server_version is None:
- version = None
- else:
- my_version = getattr(getattr(oscar.snac, 'family_x%02x' % fam), 'version', None)
- if my_version == server_version or my_version is None:
- version = None
- else:
- version = my_version
- flags = None if version is None else 32768
- if version:
- ver_tlv = oscar.util.tlv(1, 2, version)
- ver_tlv = pack('!H', len(ver_tlv)) + ver_tlv
- else:
- ver_tlv = ''
- log.debug('sending snac: fam=0x%02x, sub=0x%02x, req=0x%04x', fam, sub, req_id)
- log.debug_s('\t\tdata=%r', data)
- to_send = pack('!HHHI', fam, sub, flags, req_id) + ver_tlv + data
- self.send_flap(2, to_send)
- if (fam, sub) in self.rates:
- rclass = self.snac_rate_class(fam, sub)
- (rclass.current_level, rclass.last_time) = self.calc_rate_level(rclass)
- clevel = rclass.current_level
- i = sorted(list(self._get_rate_lvls(rclass)) + [
- clevel]).index(clevel)
- (hi, lo) = ('disconnect', 'limit', 'alert', 'clear', 'max')[i:i + 2]
- if not hi == 'clear' and lo == 'max':
- log.debug('current rate level is: %s < %d < %s', hi, clevel, lo)
-
-
-
-
- def channel_1(self):
- log.info('got channel 1 (new connection) flap')
- to_send = pack('!I', 1)
- if self.cookie is not None:
- to_send += oscar.util.tlv(6, self.cookie)
- self._lock.__enter__()
-
- try:
- self.cookie = None
- finally:
- pass
-
-
- self.send_flap(1, to_send)
-
- try:
- if not self.on_connect:
- pass
- self.default_cb(self)
- except StopIteration:
- pass
-
- del self.on_connect
- self.on_connect = None
-
-
- def channel_2(self):
- hdr = unpack_named('!HHHI', 'fam', 'sub', 'flags', 'req', self.data[:self.snac_hdr_size])
- data = self.data[self.snac_hdr_size:]
- log.debug('got channel 2 (snac data) flap. fam=0x%02x, sub=0x%02x, req=0x%04x', hdr.fam, hdr.sub, hdr.req)
- log.debug_s('\t\tdata=%r', data)
- snac = Storage(hdr = hdr, data = data)
- if snac.hdr.flags & 32768:
- log.debug('got version data for snac, trimming')
- snac_ver_fmt = (('tlvs_len', 'H'), ('tlvs', 'tlv_list_len', 'tlvs_len'))
- (tlvs_len, ver, snac.data) = oscar.util.apply_format(snac_ver_fmt, snac.data)
-
- if self.is_ignored(snac):
- log.debug('Ignored snac: %r', snac)
- return None
-
- cbs = self.callbacks
-
- try:
- if snac.hdr.req in cbs:
- call_later = []
- for func, args, kwargs in cbs[snac.hdr.req]:
- if snac.hdr.flags & 1:
- call_later.append((func, args, kwargs))
-
- if isgeneratormethod(func):
-
- try:
- func((self, snac) + args)
- except StopIteration:
- pass
- except:
- None<EXCEPTION MATCH>StopIteration
-
-
- None<EXCEPTION MATCH>StopIteration
- func(self, snac, *args, **kwargs)
-
- self._lock.__enter__()
-
- try:
- if not call_later:
- cbs.pop(snac.hdr.req)
- else:
- cbs[snac.hdr.req] = call_later
- finally:
- pass
-
- elif self.on_incoming is None:
- self.default_cb(self, snac)
- elif isgeneratormethod(self.on_incoming):
-
- try:
- self.on_incoming((self, snac))
- except StopIteration:
- pass
- except Exception:
- print repr(snac)
- raise
- except:
- None<EXCEPTION MATCH>StopIteration
-
-
- None<EXCEPTION MATCH>StopIteration
- self.on_incoming(self, snac)
- except oscar.snac.SnacError:
- e = None
- (fam, _) = ()
- (sub, _) = e.args[:2]
- if (fam, sub) in self.ignored_errors:
- log.error('SNAC error occured: %r', snac)
- else:
- hub.get_instance().on_error(e)
- except:
- (fam, sub) in self.ignored_errors
-
-
-
- def is_ignored(self, snac):
- if (snac.hdr.fam, snac.hdr.sub) in self.ignored_snacs:
- return True
-
-
- ignored_snacs = [
- (1, 19)]
- ignored_errors = [
- (1, 13),
- (21, 2),
- (19, 1),
- (21, 5)]
-
- def channel_4(self):
- log.info('got channel 4 (close connection) flap')
- fmt = (('tlvs', 'tlv_dict'),)
- (tlvs, data) = oscar.unpack(fmt, self.data)
- if (try_this,)((lambda : ord(tlvs[9][-1])), False):
- if not self.on_close:
- pass
- self.default_cb(self, oscar.protocol.Reasons.OTHER_USER)
- elif not self.on_close:
- pass
- self.default_cb(self)
- del self.on_close
- self.on_close = None
- self.close_when_done()
-
-
- def unknown_channel(self):
- log.warning('Unknown channel for data: %r', self.data)
-
-
-